package com.jietong.rfid.uhf.dao.impl;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import android_serialport_api.service.SerialPortService;
import android_serialport_api.service.impl.SerialPortServiceImpl;

import com.jietong.rfid.uhf.callback.CallBack;
import com.jietong.rfid.uhf.command.R2000Command;
import com.jietong.rfid.uhf.mode.R2000DataParseManage;
import com.jietong.rfid.util.AntStruct;
import com.jietong.rfid.util.BitOperation;
import com.jietong.rfid.util.DataConvert;
import com.jietong.rfid.util.FrequencyPoint;
import com.jietong.rfid.util.VerificationData;

public class R2000Reader extends R2000DataParseManage {

	private R2000ReaderThread r2000ReaderThread = null;
	private boolean isSerialPortConnect;
	private CallBack.R2000 callBack;
	private InputStream in = null;
	private int port = 115200;
	public String host = "";

	void setHost(String host, int baudRate) {
		String comm = host.substring(0, 5);
		isSerialPortConnect =  comm.equals("/dev/");
		this.host = host;
		port = baudRate;
		if (isSerialPortConnect) {
			if(baudRate == 0){
				port = 115200;// ZL set 230400
				baudRate = port;
			}
		} else {
			if(baudRate == 0){
				port = 20058;
				baudRate = port;
			}
		}
	}

	boolean serialPortConnect = false;
	boolean firstThread = false;
	
	boolean connect(CallBack.R2000 callBack) {
		this.callBack = callBack;
		try {
			if (isSerialPortConnect) {
				SerialPortService serialPortService = new SerialPortServiceImpl();
				serialPort = serialPortService.open(host, port);
				if (null != serialPort) {
					communicationMode = host;
					serialPortConnect = true;
					in = serialPort.getInputStream();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(null != callBack && serialPortConnect){
			r2000ReaderThread = new R2000ReaderThread(in, callBack);
			r2000ReaderThread.start();
			firstThread = true;
		}
		return serialPortConnect;
	}
	
	boolean disconnect() {
		if (null != serialPort) {
			SerialPortService serialPortService = new SerialPortServiceImpl();
			if (null != r2000ReaderThread) {
				r2000ReaderThread.interrupt();
				//r2000ReaderThread.stopTask();
			}
			serialPortService.close(serialPort);
			serialPort = null;
			return true;
		}
		return false;
	}
	
	String version() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_VERSION, null, 0)) {
			if(null == callBack){
				readData();
			}
			if (getCallBack(buffer,bufferLength, R2000Command.UHF_GET_VERSION, 800)) {
				if (bufferLength.array()[0] != 18 && buffer.array()[0] != VerificationData.HOST_ERROR) {
					String ver = new String(buffer.array()).trim();
					setVersion(ver);
					return ver;
				}
			}
		}
		return null;
	}
	
	@Deprecated
	boolean invOnce() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_INV_ONCE, null, 0)) {
			if (getCallBack(buffer,bufferLength, R2000Command.UHF_INV_ONCE, 50)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	@Deprecated
	boolean beginInv() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_INV_MULTIPLY_BEGIN, null, 0)) {
			if (getCallBack(buffer,bufferLength, R2000Command.UHF_INV_MULTIPLY_BEGIN, 50)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	@Deprecated
	boolean stopInv() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_INV_MULTIPLY_END, null, 0)) {
			if (getCallBack(buffer,bufferLength, R2000Command.UHF_INV_MULTIPLY_END, 50)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}

	boolean invOnceV2() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_INV_ONCE_V2, null, 0)) {
			if (getCallBack(buffer,bufferLength, R2000Command.UHF_INV_ONCE_V2, 50)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}

	boolean beginInvV2() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_INV_MULTIPLY_BEGIN_V2, null, 0)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_INV_MULTIPLY_BEGIN_V2, 50)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		} 
		return false;
	}

	boolean stopInvV2() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_INV_MULTIPLY_END_V2, null, 0)) {
			if (getCallBack(buffer,bufferLength, R2000Command.UHF_INV_MULTIPLY_END_V2, 50)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	String readTagData(byte bank, byte begin, byte size,byte[] password) {
		boolean result = filterOperationAreaData(bank,begin,size);
		if(!result){
			return null;
		}
		int length = size * 2;
		if (length < 1) {
			return null;
		}
		byte sendBuf[] = new byte[256];
		int bufsize = 7;
		sendBuf[0] = (byte) bank;
		sendBuf[1] = (byte) begin;
		sendBuf[2] = (byte) size;
		System.arraycopy(password, 0, sendBuf, 3, 4);
		ByteBuffer buffer = ByteBuffer.allocate(500);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_READ_TAG_DATA, sendBuf, bufsize)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_READ_TAG_DATA, 500)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					byte[] total = Arrays.copyOf(buffer.array(), length);
					StringBuffer sb = new StringBuffer();
					for (int i = 0; i < length; i++) {
						sb.append(DataConvert.bytesToHexString(total[i]));
					}
					return sb.toString();	
				}
			}
			return null;
		}
		return null;
	}
	
	boolean writeTagData(int bank, int begin, int length,String data, byte[] password) {
		byte buf[] = new byte[256];
		int bufsize = 3 + length * 2 + 4;
		buf[0] = (byte) bank;
		buf[1] = (byte) begin;
		buf[2] = (byte) length;
		System.arraycopy(password, 0, buf, 3, 4);
		byte[] inData = new byte[data.length() / 2];
		int count = 0;
		for (int i = 0; i < inData.length; i++) {
			int result = Integer.parseInt(data.substring(count, count + 2), 16);
			count += 2;
			inData[i] = (byte) result;
		}
		System.arraycopy(inData, 0, buf, 3 + 4, length * 2);
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_WRITE_TAG_DATA, buf, bufsize)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_WRITE_TAG_DATA, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	Map<String, Boolean> getGPIO() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_DI_STATE, null, 0)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_GET_DI_STATE, 500)) {
				return null;
			}
		}
		return null;
	}
	
	boolean setGPIO(byte port, byte state) {
		byte buf[] = new byte[32];
		if (port > 2 || port == 0) {
			return false;
		}
		buf[0] = port;
		buf[1] = state;
		ByteBuffer buffer = ByteBuffer.allocate(10);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_DO_STATE, buf, 2)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_DO_STATE, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}

	Map<String, Byte> getAntennaStatus() {
		Map<String, Byte> config = null;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_ANT_STATE, null, 0)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_GET_ANT_STATE, 5000)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR && bufferLength.array()[0] != 8) {
					byte[] _buf = buffer.array();
					int lengthChannel = DataConvert.byteToInt(_buf[0]);
					if (lengthChannel < 4) {
						return null;
					}
					config = new HashMap<String, Byte>();
					config.put("Channel", _buf[0]);
					for (int j = 0; j < lengthChannel; j++) {
						int index = j + 1;
						config.put("Ant" + index, _buf[index]);
					}
					return config;
				}
			}
		}
		return null;
	}

	boolean lockTag(byte locktType, byte lockBank,byte[] password) {
		if (password.length < 1) {
			return false;
		}
		if (locktType < 0 || locktType > 3) {
			return false;
		}
		if (lockBank < 0 || lockBank > 4) {
			return false;
		}
		byte buf[] = new byte[12];
		buf[0] = locktType;
		buf[1] = lockBank;
		System.arraycopy(password, 0, buf, 2, password.length);
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_LOCK_TAG, buf, 6)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_LOCK_TAG, 500)){
				if(buffer.array()[0] != VerificationData.HOST_ERROR){
					return true;
				}
			}
		}
		return false;
	}

	boolean killTag(byte[] accessPwd, byte[] killPwd) {
		byte buf[] = new byte[16];
		System.arraycopy(killPwd, 0, buf, 0, 4);
		System.arraycopy(accessPwd, 0, buf, 4, 4);
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_KILL_TAG, buf, 8)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_KILL_TAG, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}

	boolean setDeviceConfig(byte[] para) {
		byte buf[] = new byte[128];
		byte bufSize = 20;
		System.arraycopy(para, 0, buf, 0, bufSize);
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_CONFIGURE, buf, bufSize)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_CONFIGURE, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	/***************************** 2019-04-26 start ****************************************/
	String getDeviceNo() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_DEVICE_NO, null, 0)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_GET_DEVICE_NO, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					int deviceNo = 0;
					deviceNo |= DataConvert.byteToInt(buffer.array()[0]) << 8;
					deviceNo |= DataConvert.byteToInt(buffer.array()[1]);
					return String.valueOf(deviceNo);
				}
			}
		}
		return null;
	}

	boolean setDeviceNo(int deviceNo) {
		byte buf[] = new byte[16];
		int bufsize = 2;
		if (deviceNo < 0 || deviceNo > 65535) {
			return false;
		}
		buf[0] = (byte) (deviceNo >> 8);
		buf[1] = (byte) deviceNo;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_DEVICE_NO, buf, bufsize)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_DEVICE_NO,500)){
				if (buffer.array()[0] == VerificationData.HOST_SUCCEED) {
					return true;
				}
			}
		}
		return false;
	}
	
	int getBuzzer() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_BUZZ, null, 0)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_GET_BUZZ, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return DataConvert.byteToInt(buffer.array()[0]);
				}
			}
		}
		return -1;
	}

	boolean setBuzzer(byte buzz) {
		byte[] buf = new byte[2];
		buf[0] = buzz;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_BUZZ, buf, 1)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_BUZZ, 500)){
				if (buffer.array()[0] == VerificationData.HOST_SUCCEED) {
					return true;
				}
			}
		}
		return false;
	}
	
	boolean setWorkMode(int mode) {
		byte buf[] = new byte[8];
		int bufsize = 1;
		buf[0] = (byte) mode;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_MODE, buf, bufsize)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_MODE, 500)){
				if(buffer.array()[0] == VerificationData.HOST_SUCCEED){
					return true;
				}
			}
		}
		return false;
	}
	
	int getWorkMode() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_MODE, null, 0)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_GET_MODE, 500)) {
				if(buffer.array()[0] > -1 && buffer.array()[0] < 4){
					return DataConvert.byteToInt(buffer.array()[0]);
				}
			}
		}
		return -1;
	}
	
	int getTriggerModeDelayTime() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_TRIGGER_TIME, null, 0)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_GET_TRIGGER_TIME, 500)){
				if(buffer.array()[0] != VerificationData.HOST_ERROR){
					return DataConvert.byteToInt(buffer.array()[0]);
				}
			}
		}
		return -1;
	}
	
	boolean setTriggerModeDelayTime(byte trigTime) {
		byte buf[] = new byte[16];
		buf[0] = trigTime;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_TRIGGER_TIME, buf, 1)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_SET_TRIGGER_TIME, 500)) {
				if(buffer.array()[0] != VerificationData.HOST_ERROR){
					return true;
				}
			}
			
		}
		return false;
	}
	
	boolean setTriggerModeAlertTime(byte time) {
		byte buf[] = new byte[16];
		buf[0] = time;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_TRIGGER_ALARM, buf, 1)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_SET_TRIGGER_ALARM, 500)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	Map<String, Byte> getAdjacentDiscriminant() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_TAG_FILTER, null, 0)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_GET_TAG_FILTER, 500)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					Map<String, Byte> map = new HashMap<String, Byte>();
					map.put("enableNJ", buffer.array()[0]);
					map.put("neighJudgeTime", buffer.array()[1]);
					return map;
				}
			}
		}
		return null;
	}

	boolean setAdjacentDiscriminant(byte neighJudgeTime) {
		int bufsize = 2;
		byte[] buf = new byte[16];
		buf[0] = (byte) (neighJudgeTime > 0 ? 1 : 0); // 
		// time = 0,cancel NeighJudge??not 0??set NeighJudge
		buf[1] = neighJudgeTime;//(0 - 255)
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_TAG_FILTER, buf, bufsize)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_TAG_FILTER, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	int getOutputMode() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_OUTPUT, null, 0)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_GET_OUTPUT, 500)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return DataConvert.byteToInt(buffer.array()[0]);
				}
			}
		}
		return -1;
	}

	boolean setOutputMode(byte type) {
		byte buf[] = new byte[16];
		buf[0] = type;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_OUTPUT, buf, 1)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_SET_OUTPUT, 500)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return true;
				}
			}
		}
		return false;
	}
	
	byte [] getAntenna() {
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_ANT_CONFIG, null, 0)) {
			if (getCallBack(buffer,bufferLength,R2000Command.UHF_GET_ANT_CONFIG, 500)) {
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					return buffer.array();
				}
			}
		}
		return null;
	}

	boolean setAntenna(AntStruct ant) {
		byte[] sendAntData = setAntAllChannel(ant);
		if (null == sendAntData) {
			return false;
		}
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_ANT_CONFIG, sendAntData,R2000Command.ANT_CFG_LENGTH)) {
			if(getCallBack(buffer,bufferLength, R2000Command.UHF_SET_ANT_CONFIG, 1000)){
				if(buffer.array()[0] != VerificationData.HOST_ERROR){
					return true;
				}
			}
		}
		return false;
	}
	
	FrequencyPoint getFrequency() {
		byte buf[] = new byte[16];
		buf[0] = 0x01;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_FREQUENCY,buf, 1)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_GET_FREQUENCY, 500)){
				FrequencyPoint frequencyPoint = new FrequencyPoint();
				int length = 8;
				byte[] result = Arrays.copyOf(buffer.array(), length);
				int type = DataConvert.byteToInt(result[0]);
				if (type == 5) {
					frequencyPoint.setFrequencyHopping(frequencyPoint(result));
				} else if (type == 6) {
					frequencyPoint.setFrequencyFixed(frequencyFixed(result));
				}
				frequencyPoint.setType(type);
				return frequencyPoint;
			}
		}
		return null;
	}
    
	boolean setFrequency(int type, double frequencyFixed,boolean[] frequencyHopping) {
		if (type < 0 || type > 6) {
			return false;
		}
		if (null == frequencyHopping || frequencyHopping.length > 50) {
			return false;
		}
		byte buf[] = new byte[16];
		buf[0] = (byte) type;
		if (type == 5) {
			byte[] hopping = frequencyHoppingFilter(frequencyHopping);
			System.arraycopy(hopping, 0, buf, 1, 7);
		} else if (type == 6) {
			if (frequencyFixed > 1000) {
				return false;
			}
			int value = (int) (frequencyFixed * 1000);
			byte[] fixed = frequencyFixed(value);
			System.arraycopy(fixed, 0, buf, 1, 3);
		}

		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_FREQUENCY, buf, 8)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_FREQUENCY, 500)){
				if (buffer.array()[0] == VerificationData.HOST_SUCCEED) {
					return true;
				}
			}
		}
		return false;
	}
	
	Map<String, Integer> getInvPatternConfig() {
		Map<String, Integer> config = null;
		byte buf[] = new byte[16];
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_INV_PATTERN_CONFIG, buf, 1)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_GET_INV_PATTERN_CONFIG,500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					int length = 4;
					byte[] _buffer = Arrays.copyOf(buffer.array(), length);
					int[] value = new int[length];
					int i = 0;
					for (byte data : _buffer) {
						value[i] = DataConvert.byteToInt(data);
						i++;
					}
					config = new HashMap<String, Integer>();
					config.put("session", value[0]);
					config.put("qValue", value[1]);
					config.put("tagFocus", value[2]);
					config.put("abValue", value[3]);
					return config;
				}
			}
		}
		return null;
	}

	boolean setInvPatternConfig(byte session,byte qValue, byte tagFocus, byte abValue) {
		byte buf[] = new byte[16];
		buf[0] = session;
		buf[1] = qValue;
		buf[2] = tagFocus;
		buf[3] = abValue;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_INV_PATTERN_CONFIG, buf, 4)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_INV_PATTERN_CONFIG, 500)){
				if (buffer.array()[0] == VerificationData.HOST_SUCCEED) {
					return true;
				}
			}
		}
		return false;
	}
	
	Map<String, Boolean> getInvOutPutData() {
		Map<String, Boolean> config = null;
		byte buf[] = new byte[16];
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_GET_INV_OUTPUT_DATA, buf, 1)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_GET_INV_OUTPUT_DATA, 500)){
				if (buffer.array()[0] != VerificationData.HOST_ERROR) {
					boolean[] value = BitOperation.byteToBooleans(buffer.array()[0]);
					config = new HashMap<String, Boolean>();
					config.put("antenna", value[0]);
					config.put("rssi", value[1]);
					config.put("deviceNo", value[2]);
					config.put("accessDoorDirection", value[3]);
					return config;
				}
			}
		}
		return null;
	}

	boolean setInvOutPutData(byte antenna, byte rssi,byte deviceNo, byte accessDoorDirection) {
		byte buf[] = new byte[16];
		buf[0] = antenna;
		buf[1] = rssi;
		buf[2] = deviceNo;
		buf[3] = accessDoorDirection;
		byte _buf = BitOperation.bytesToByte(buf);
		buf[0] = _buf;
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_SET_INV_OUTPUT_DATA, buf, 1)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_SET_INV_OUTPUT_DATA, 500)){
				if (buffer.array()[0] == VerificationData.HOST_SUCCEED) {
					return true;
				}
			}
		}
		return false;
	}
	
	boolean factoryDataReset() {
		byte buf[] = new byte[16];
		ByteBuffer buffer = ByteBuffer.allocate(100);
		IntBuffer bufferLength = IntBuffer.allocate(1);
		if (sendData(R2000Command.UHF_FACTORY_DATA_RESET, buf, 1)) {
			if(getCallBack(buffer,bufferLength,R2000Command.UHF_FACTORY_DATA_RESET, 500)){
				if (bufferLength.array()[0] == 1 && buffer.array()[0] == VerificationData.HOST_SUCCEED) {
					return true;
				}
			}
		}
		return false;
	}
	
	/***************************** 2019-04-26 end ****************************************/
	
	class R2000ReaderThread extends Thread {

		InputStream in;
		CallBack.R2000 callBack;
		R2000Reader reader;

		boolean flag = true;

		public void stopTask() {
			flag = false;
		}

		public R2000ReaderThread() {
		}

		public R2000ReaderThread(InputStream in, CallBack.R2000 callBack) {
			this.in = in;
			this.callBack = callBack;
		}

		@Override
		public void run() {
			try {
				byte[] buffer = new byte[1024];
				int len = -1;
				while (!isInterrupted()) {
						while (in.available() > 0) {
							if((len = in.read(buffer)) > -1){
							byte[] buf = Arrays.copyOf(buffer, len);
							if (null != callBack) {
								if (len > 0) {
									deviceTransBufferV2(buf, callBack);
								}
							}
							Thread.sleep(50);
						}
					}
				}
			} catch (InterruptedException e) {
				System.out.println(Thread.currentThread().getName() + " ("	+ this.getState() + ") catch InterruptedException.");
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				
			}
		}
	}
}
